﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Configuration;
using Fixtures;
using FluentAssertions;

namespace Repository.Tests
{
    [TestClass]
    public class PatientRepositoryTest
    {
        private string _connectionString = ConfigurationManager.ConnectionStrings[Helpers.Constants.CONNECTION_STRING_NAME].ConnectionString;

        [TestMethod]
        public void AddPatient_ShouldSaveSuccessfully()
        {
            // Arrange
            var repo = new PatientRepository(_connectionString);
            var patient = PatientFixture.GetPatient();
            patient.Id = 0;
            patient.MedicalRecordNumber = 0;            

            // Act
            var patientMRN = repo.AddPatient(patient);

            // Assert
            patientMRN.Should().BeGreaterThan(0);
        }

        [TestMethod]
        public void GetPatient_ShouldReturnPatientThePatientAskedFor()
        {
            // Arrange
            var repo = new PatientRepository(_connectionString);
            var patient = PatientFixture.GetPatient();
            patient.Id = 0;
            patient.MedicalRecordNumber = 0;
            var patientMRN = repo.AddPatient(patient);
            
            // Act
            var patientRetrieved = repo.GetPatient(patientMRN);

            // Assert
            patientRetrieved.Should().NotBeNull();
            patientRetrieved.MedicalRecordNumber.Should().Be(patientMRN);
            patientRetrieved.Name.Should().Be(patient.Name);
            patientRetrieved.Gender.Should().Be(patient.Gender);
            patientRetrieved.DateOfBirth.Should().Be(patient.DateOfBirth);
            patientRetrieved.EmailAddress.Should().Be(patient.EmailAddress);
            patientRetrieved.PhoneNumber.Should().Be(patient.PhoneNumber);
            patientRetrieved.HomeAddress.Line1.Should().Be(patient.HomeAddress.Line1);
            patientRetrieved.HomeAddress.Line2.Should().Be(patient.HomeAddress.Line2);
            patientRetrieved.HomeAddress.City.Should().Be(patient.HomeAddress.City);
            patientRetrieved.HomeAddress.State.Should().Be(patient.HomeAddress.State);
            patientRetrieved.HomeAddress.PostalCode.Should().Be(patient.HomeAddress.PostalCode);
        }

        [TestMethod]
        public void GetPatient_ShouldThrowException_IfMedicalRecordNumberIsNotFound()
        {
            // Arrange
            var repo = new PatientRepository(_connectionString);

            // Act
            try
            {
                repo.GetPatient(-1);
            }
            catch (Exception ex)
            {
                // Assert
                ex.Message.Should().Be(string.Format("Patient with medical record number: {0} cannot be found.", -1));
            }
        }

        [TestMethod]
        public void UpdatePatient_ShouldUpdate_IfPatientIsFound()
        {
            // Arrange
            var repo = new PatientRepository(_connectionString);
            var patient = PatientFixture.GetPatient();
            patient.Id = 0;
            patient.MedicalRecordNumber = 0;
            
            var patientMRN = repo.AddPatient(patient);
            var patientToUpdate = repo.GetPatient(patientMRN);
            patientToUpdate.Name = patient.Name + "x";
                        
            // Act
            repo.UpdatePatient(patientToUpdate);

            // Assert
            var updatedPatient = repo.GetPatient(patientMRN);
            updatedPatient.Name.Should().Be(patientToUpdate.Name);
        }

        [TestMethod]
        public void UpdatePatient_ShouldThrowException_IfMedicalRecordNumberIsNotFound()
        {
            // Arrange
            var repo = new PatientRepository(_connectionString);
            var patient = PatientFixture.GetPatient();            
            patient.MedicalRecordNumber = -1;

            // Act
            try
            {
                repo.UpdatePatient(patient);
            }
            catch (Exception ex)
            {
                // Assert
                ex.Message.Should().Be(string.Format("Patient with medical record number: {0} cannot be found.", -1));
            }
        }
    }
}
